iT邦幫忙

2023 iThome 鐵人賽

DAY 3
0
Vue.js

Nuxt 3 初學者指南:30天從基礎到實踐系列 第 3

Day 3 – Nuxt 3 核心功能概念(下)

  • 分享至 

  • xImage
  •  

今天將繼續介紹 Nuxt 3 的核心功能概念,若還沒讀過 Day 2 – Nuxt 3 核心功能概念(上) 的朋友們也別忘了在實作前先認識這些重要的概念!

Server Engine

Nuxt 3 中提到一個新的詞 — Nitro,但它到底是什麼?用途為何?又有哪些值得一探究竟的特性呢?

Nuxt 3 is powered by a new server engine, Nitro.

以 Nitro 作為伺服器引擎帶來許多益處,除了 跨平台支援(Node.js、瀏覽器等多種環境下皆可運行),更具有 無伺服器(Serverless) 特性,開箱即用;先前提到的 Edge-Side Rendering(邊緣渲染 ESR) 也是透過 Nitro 消除原先 Nuxt 2 將網站部屬到邊緣服務的限制。另外 Nitro 也包含了以下特點:

  • 輕鬆建立與管理 API 路由請求。
  • 將程式碼拆分並實現非同步加載入提高性能。
  • 提供靜態網站和無伺服器網站的混合模式。
  • 支援 Hot Module Reloading 修改後即可看到更新的頁面。

Modules

Nuxt 模組系統是以框架的核心邏輯加以擴展,並簡化整合的配置流程,更進一步打包為 npm 套件達到獨立且可重用的優勢,使開發能夠更快速簡潔;此篇章著重於概念與如何實現,實際有提供哪些模組可以參考 → Nuxt 模組列表

使用

選擇需要的模組,安裝完後將它們加到 nuxt.config.ts 文件的 module 中,定義的形式如下:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    // 官方推薦用法:使用 package 的名稱
    '@nuxtjs/example',

    // 載入本地目錄之模組
    './modules/example',

    // 帶有選項之模組
    ['./modules/example', { token: '123' }]

    // 在行內定義模組
    async (inlineOptions, nuxt) => { }
  ]
})

ES Modules

📜 TL;DR

ES Modules 是一種模組編寫語法,對於舊有的 Node.js 可能會帶來相容性問題。解決這些問題需要調整函式庫的文件結構和 package.json,以確保在不同的環境中能正確運行。

背景

開始介紹 Nuxt 3 是如何相容 ES Modules 之前,讓我們先來好好了解 ES Modules 是什麼。

  • ES Modules(ESM)

    ECMAScript 規範的編寫模組之標準。提供組織 JavaScript 程式碼的有效方式,有助於提高可讀性、可維護性和可擴展性,並透過 importexport 在模組間共享變數、函式和 Class。

    // 導入模組
    import a from './a'
    
    // 導出變數
    export { a }
    
  • CommonJS Modules(CJS)

    是 Node.js 引入的一種模組編寫格式,與為了解決早期 JavaScript 沒有統一標準的問題。使用 require 函式將模組導入,並以 module.exports 物件將變數、函式、物件導出。

    // 導入模組
    const a = require('./a')
    
    // 導出變數
    module.exports.a = a
    
  • ESM vs CJS

    目前以 ESM 為模組標準的主流,它相較於 CJS 有以下幾點優勢:

    • ESM 支援非同步載入模組;CJS 是同步機制,因此模組載入時會阻止程式碼的進行。
    • ESM 是原生支援的;CJS 則需要打包工具的支援,以在瀏覽器中運行。
    • ESM 模組有自己的作用域;CJS 模組為全域共享,可能導致變數衝突和作用域問題。
  • 'Native' ESM

    • '原生' ESM 是指在支援 ESM 語法的 JavaScript 環境中,直接使用 ESM 語法的模組。

    • 以往安裝套件至模組時會發現,一個函式庫可能會同時提供 CJS 和 ESM,讓我們可以依需求選擇。

    • 然而目前最新的 Node.js 版本中,我們可以在 Node.js 中使用原生 ESM 模組,啟用 ESM 語法的兩種最常見方法是:

      1. (官方推薦)使用 .mjs 文件副檔名。
      2. package.json 中設置 type: 'module',並繼續使用 .js 副檔名。
  • 如何在 Node.js 中有效導入?

    當你使用 import 導入而非 require 時,Node.js 會以不同方式解析,以下為 Node.js 支持的導入類型:

    • .mjs 結尾的檔案 - 預計使用 ESM 語法。
    • .cjs 結尾的檔案 - 預計使用 CJS 語法。
    • .js 結尾的檔案 - 預計使用 CJS 語法,除非它們的 package.json 具有 type: 'module'
  • 上述造成的問題?

    如果嘗試在 Node.js ESM 環境中導入具有 .esm.js 文件的 package,將會導致無法運作且收到錯誤訊息。

解決

如果遇到上述的問題,通常來說是函式庫的開發者需要進行修補,但我們也能做以下的措施:

  • 告訴 Nuxt 不要導入這些函式庫,需將它們加到 build.transpile

    // nuxt.config.ts
    export default defineNuxtConfig({
      build: {
        transpile: ['sample-library']
      }
    })
    
  • 手動設定函式庫的 CJS 版本。

    // nuxt.config.ts
    export default defineNuxtConfig({
      alias: {
        'sample-library': 'sample-library/dist/sample-library.cjs.js'
      }
    })
    
  • 依照不同的依賴去進行相對應的預設導出。更多細節可參考 此處

另外,對於函式庫的開發者來說,若要修復 ESM 的兼容性問題,主要有兩個選擇:

  1. 將 ESM 文件重命名為 .mjs 或將整個庫設置為 ESM-only
  2. require 替換成 import

TypeScript

Nuxt 3 緊跟著 Vue 3 的推出而誕生。相比於 Nuxt 2 它更全面的支援了 TypeScript,這有助於我們在開發時利用它強大的型別檢查以減少錯誤,並提高程式碼的可讀性。

Type-checking

預設情況下,Nuxt 在 nuxi devnuxi build 階段省略了型別檢查功能以提升效能;但我們能透過

  1. vue-tsctypescript 安裝為 devDependency,並在 nuxt.config.ts 文件中啟用 typescript.typeCheck 選項。
  2. 使用 yarn nuxi typecheck 來手動的在開發或建構時啟用型別檢查。

Auto-generated Types

當你運行 nuxi devnuxi build 時,Nuxt 會產生以下文件,以支援 IDE 的型別檢查:

  • .nuxt/nuxt.d.ts 包含所有使用的模組型別。
  • .nuxt/tsconfig.json 包含建議專案基本的 TypeScript 設置。

Stricter Checks

TypeScript 提供更高的程式碼安全性和分析功能,要啟用嚴格的型別檢查,需要更新 nuxt.config.ts 如下:

// nuxt.config.ts
export default defineNuxtConfig({
  typescript: {
    strict: true
  }
})

🌞 Upcoming

花了兩天介紹 Nuxt 3 重要的核心功能概念,明天開始就要進入實作階段並建立你的第一個 Nuxt 專案!


參考資料

Server Engine
Modules
ES Modules
TypeScript
【程式語言 - Javascript】 ESM 與 CJS


上一篇
Day 2 – Nuxt 3 核心功能概念(上)
下一篇
Day 4 – 建立第一個 Nuxt 3 專案
系列文
Nuxt 3 初學者指南:30天從基礎到實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言